﻿#region License

/*
 © 2012 Alex Kazaev
 * FolderDrive project [http://folderdrive.codeplex.com/]
 * Licensed under Ms-PL license [http://www.opensource.org/licenses/MS-PL]
 */

#endregion License

using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using FolderDrive.ViewModels;
using Application = System.Windows.Application;

namespace FolderDrive
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
    public partial class MainWindow
    {
        #region fields

        private readonly FolderDriveViewModel vm = new FolderDriveViewModel();
        private NotifyIcon notifyIcon;
        private WindowState storedWindowState = WindowState.Normal;

        #endregion fields

        #region constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindow"/> class.
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            var iconUri = new Uri(@"pack://application:,,,/FolderDrive;component/Resources/harddrive.ico");
            using (Stream iconStream = Application.GetResourceStream(iconUri).Stream)
            {
                notifyIcon = new NotifyIcon
                               {
                                   BalloonTipText = "The FolderDrive window has been minimised. Click the tray icon to show.",
                                   BalloonTipTitle = "FolderDrive",
                                   Text = "FolderDrive",
                                   ContextMenuStrip = CreateMenu(),
                                   Icon = new Icon(iconStream)
                               };
            }
            notifyIcon.MouseClick += OnNotifyIconMouseClick;
            DataContext = vm;
            addMappingControl.Finished += AddMappingFinished;
            infoControl.Finished += InfoFinished;
            optionsControl.Finished += OptionsFinished;
            vm.ShowMappingGrid();
            WindowState = vm.GetDefaultWindowState();
            ShowTrayIcon(true);
            OnWindowStateChanged(null, null);
        }

        #endregion constructor

        #region private methods

        /// <summary>
        /// Called when the add mapping button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnAddMappingClick(object sender, RoutedEventArgs e)
        {
            vm.ShowAddMapping();
        }

        /// <summary>
        /// Called when the remove selected button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnRemoveSelectedClick(object sender, RoutedEventArgs e)
        {
            vm.RemoveSelectedItems();
        }

        /// <summary>
        /// Called when the window state changes.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OnWindowStateChanged(object sender, EventArgs e)
        {
            if (WindowState == WindowState.Minimized)
            {
                MinimizeWindow();
            }
            else
                storedWindowState = WindowState;
        }

        /// <summary>
        /// Called when the Info control needs to be hidden.
        /// </summary>
        /// <param name="result">if set to <c>true</c> [result].</param>
        private void InfoFinished(bool result)
        {
            vm.ShowMappingGrid();
        }

        /// <summary>
        /// Called when the Options control needs to be hidden.
        /// </summary>
        /// <param name="result">if set to <c>true</c> [result].</param>
        private void OptionsFinished(bool result)
        {
            vm.ShowMappingGrid();
        }

        /// <summary>
        /// Called when the add mapping control needs to be hidden.
        /// </summary>
        /// <param name="result">if set to <c>true</c> [result].</param>
        private void AddMappingFinished(bool result)
        {
            if (result)
            {
                vm.AddItem(vm.MappingViewModel.MappingPreference);
            }
            vm.ShowMappingGrid();
        }

        /// <summary>
        /// Called when the window starts closing.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        private void OnWindowClosing(object sender, CancelEventArgs e)
        {
            bool isClosing = vm.Closing();
            e.Cancel = !isClosing;
            if (isClosing)
            {
                if (notifyIcon != null)
                {
                    notifyIcon.Dispose();
                    notifyIcon = null;
                }
            }
            else
            {
                MinimizeWindow();
            }
        }

        void OnNotifyIconMouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Show();
                WindowState = storedWindowState;
            }
        }

        /// <summary>
        /// Changes the visbility of tray icon
        /// </summary>
        /// <param name="show">if set to <c>true</c> shows the icon.</param>
        private void ShowTrayIcon(bool show)
        {
            if (notifyIcon != null)
                notifyIcon.Visible = show;
        }

        /// <summary>
        /// Called when the info button is  clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnInfoButtonClick(object sender, RoutedEventArgs e)
        {
            vm.ShowInfo();
        }

        /// <summary>
        /// Called when the options button is clicked.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void OnOptionsButtonClick(object sender, RoutedEventArgs e)
        {
            vm.ShowOptions();
        }

        /// <summary>
        /// Handles clicks on update program icon
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnUpdateMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            vm.UpdateSoft();
        }

        /// <summary>
        /// Creates the context menu for app tray icon
        /// </summary>
        /// <returns>initialized ContextMenuStrip instance </returns>
        private ContextMenuStrip CreateMenu()
        {
            var result = new ContextMenuStrip();
            result.Items.Add(new ToolStripMenuItem("Restore", null, (object sender, EventArgs args) =>
            {
                Show();
                WindowState = storedWindowState;
            }));
            result.Items.Add(new ToolStripSeparator());
            result.Items.Add(new ToolStripMenuItem("Exit", null, (object sender, EventArgs args) =>
            {
                vm.Closing(true);
                notifyIcon.Dispose();
                notifyIcon = null;
                Application.Current.Shutdown();
            }));
            return result;
        }

        /// <summary>
        /// Minimizes the window.
        /// </summary>
        private void MinimizeWindow()
        {
            Hide();
            if (notifyIcon != null && vm.OptionsViewModel.ShowTooltip)
            {
                notifyIcon.ShowBalloonTip(2000);
                vm.OptionsViewModel.ShowTooltip = false;
            }
        }
        #endregion private methods
    }
}